The GOLDDB unit provides a complete set of routines for
developing database applications such as a customer list or parts
inventory. Developers of database toolkits often complicate the
final product by offering several levels of access to database
information. The simplest level doesn't allow enough flexibility
while the deepest level becomes so complicated that a complete
understanding of database management and indexing is required.
Keeping the developer in mind, we have attempted to deliver real
flexibility while making the GOLDDB unit as simple as possible.
File Support
The GOLDDB unit supports the extremely popular dBase III+ file
format (dBase is a trademark of Borland International). Only one
index file per database is permitted, and the index file name uses
the associated database's file name while appending our own .GDX
(Gold Database Index) extension. For example, if the database was
named PARTS.DBF, the index would be named PARTS.GDX. Behind the
scenes, Gold uses a custom implementation of Btree indexing.
GOLDDB also supports the standard .DBT memo file.
General Database Activities
Following are the general routines that relate to the general database access.
DBFExist(FN: PathStr): boolean;
Determines whether or not a database file exists. Sometimes the user may not provide the .DBF extension, so DBFExist forces this extension before making its determination. To ensure that the application flows smoothly as files are opened, it is recommended that you check for their existence first.
The following code sample demonstrates checking for the existence of the data file.
begin { main }
if DBFExist('DEMCUST') then
begin
Handle := DbOpenDataSet('DEMCUST.DBF');
if (Handle = 0) then
PromptOK(' DATA ERROR ','Unable to open DEMCUST.DBF
or one of its related files.')
else
{ Data activity takes place here }
if Handle > 0 then
DbCloseDatabase(Handle);
end;
Clear(LightGrayOnBlack,' ');
end.
The above code illustrates the use of the database handle.
Since Gold allows you to open multiple databases at any one time,
you need some way of informing Gold which database you want to work
with. When a database is opened, Gold returns a handle. The
procedure DbSetActiveDatabase is used to set the focus to a
specific database, by passing a specific handle. All database
operations are directed to the database with focus. Notice that
this same handle is used in the call to DbCloseDatabase. These
primary database arrangement functions are defined as follows:
DbOpenDataSet(DBFile: pathstr): integer;
Opens, validates and assigns a handle to the specified
database. If it exists, the associated index file is also opened
and validated. The integer value that is returned becomes the
handle that identifies the database just opened, i.e. the database
with focus. A returned handle value of zero implies that the data
file did not validate correctly and may be corrupt.
GOLDDB maintains an internal list of pointers, each of which
individually points to the associated attributes of the opened data
files. The file handle is actually the value of the associated
sequential entry within this list.
DbSetActiveDataBase(Handle:integer);
If more than one database is opened at a time, focus may be
changed to another file by specifying its assigned handle. All
subsequent activity associated with a database is focused on the
new file handle until focus is changed again or the file is closed.
DbCloseDataBase(Handle: integer);
After all activity has been completed surrounding the data, a
database must be closed to free up the memory that was allocated
for its use. The handle identifies the database that will be
closed.
Listed below are some other common data management routines.
DbSetFullStrings(On: boolean);
Inside a dBase file, all data is stored as "space padded"
strings. This procedure instructs Gold on how to return data from
each field. Setting the parameter to FALSE will strip all the
trailing spaces from the data before it is returned to the
application. The default is TRUE, so that the complete length of
the field is returned each time.
DbIndexedField: integer;
Returns the field used for the database index. A value of zero
implies that the index file is not valid or does not exist.
DbSeqSearch(var RecNo: longint; FieldNo: integer;
SearchTxt: String): boolean;
Instructs Gold to perform a sequential search fo the database,
i.e. a non-indexed search which checks the field in natural or
stored order. A database index is not used for this search, even if
one exists. Passing a value of zero to RecNo signals the search to
begin at record one, any other value begins at the specified
record.
DbCloseAllDatabases;
If more than one database has been opened to perhaps compare
data or design some relational report about the data, all opened
databases may be closed by calling this one procedure. This is in
lieu of running down the list of opened data files and closing them
one at a time.
What's the Header?
Each .DBF file contains certain information which defines the
database characteristics along with the fields it contains. This
data is stored at the beginning of the DBS file and is referred to
as the header. The first 32 bytes of the header is information
which specifically pertains to the .DBF file, e.g. version number,
last data it was modified, etc. There is an additional 32 bytes
added to the header for each field within the database.
The GOLDDB unit maintains a record depicting the first 32
bytes of the header and is defined as follows:
HeaderInfo = record
VersionNumber: byte;
Update: array [1..3] of byte;
NbrRec: longint;
HdrLen: integer;
RecLen: integer;
Reserved: array [1..20] of char;
end;
You do not need to access this record directly. Use the
following list of routines to retrieve this information.
DbGetVersion: byte;
Returns the version byte of the database file. This is
generally one of two values, either a 3 ($03) or a 131 ($83). A
value of 131 ($83) indicates that at least one memo field exists in
the database. Some third party dBase-clone vendors have decided to
use this version byte as their finger print, modifying it to their
own value. When a database is opened Gold inspects the version
byte to ensure that GOLDDB is using a true dBase III+ compatible
file.
DbGetUpDate: dates;
Another part of the header is a date which represents the last
time a value was changed in the database. This function returns a
longint value of type dates, that may be converted to a string
value using JultoStr.
DbTotalFields: integer;
Represents the total number of fields defined in the database.
DbGetNumRecs: longint;
Each time a record is added to the data file, this value is
incremented by one. It represents all records whether or not they
have been marked as deleted.
DbGetHdrLen: integer;
The header length is made up of a multiple of 32 byte sections
and is terminated with a single <CR> ($0D) character. The first 32
byte section contains the file specific information while the
remaining sections are field definitions. The header length is
inclusive of the end-of-header character.
DbGetRecLen: word;
The first byte of each record is the status byte. The record
length is defined as all the individual field lengths added
together plus one byte (status byte).
DbCurrRecNum: longint;
The current record is the record being held in the work space,
i.e. the location of the database cursor. GOLDDB unit maintains a
small portion of memory which is the exact size of a record from
the associated database.
Field Specifics
Records in a DBF file are said to be of fixed length. This
means that each record is exactly the same length, regardless of
the data stored within. Each record is made up of a pre-defined set
of fields. Each field has its own definition which resides in the
database header. The GOLDDB unit maintains a record type which is
defined as follows:
FieldDesc = record
FdName: array [1..11] of char;
FdType: char;
Reserved1: array [1..4] of char;
FdLength: byte;
FdDec: byte;
Reserved2: array [1..14] of char;
end;
You do not need to access this record directly. Use the
following list of routines to retrieve this information.
DbGetFldName(FieldNo: integer): string;
Each field has its own name. The name may be no longer than 10
characters and must begin with an alpha character. The remaining
characters may be alphanumeric or the underscore character.
DbGetFldType(FieldNo: integer): char;
GOLDDB supports only dBase III+ compatible field types as follows:
C - Character
N - Numeric (includes floating)
L - Logical
D - Date
M - Memo
DbGetFldLength(FieldNo: integer): integer;
Each field type has its own limitations. The supported field
types have the following field length definitions:
C - 1 to 254 characters
N - 1 to 19 characters
L - 1 character ( T or F )
D - 8 characters
M - 10 characters
DbGetFldDec(FieldNo: integer): integer;
When a field is defined as a numeric type it may also have a
number of decimal places. This value may not be greater than [(the
defined field length) - 2] and may never be greater than 9.
Retrieving Field Information
Behind the scenes, all data in a .DBF file is stored in
character form. Each of the following routines performs an
appropriate conversion and returns the data in its native form. Any
time information is requested about a specific field the whole
record is loaded into the internal work space. This is so that
subsequent requests from the same record will not have to be read
from the storage media.
The following code fragment demonstrates the ease of